<?php
/**
 * Created by PhpStorm.
 * User: zd
 * Date: 2018/8/15
 * Time: 17:51
 */

namespace app\api\service;


use app\lib\enum\AuthStatusEnum;
use app\lib\enum\ScopeEnum;
use app\lib\exception\ForbiddenException;
use app\lib\exception\TokenException;
use think\Cache;
use think\Exception;
use think\Request;

class Token
{
    /**
     * 返回token
     * @return string
     */
    public static function generateToken()
    {
        $randChars = getRandChar(32);
        $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
        $salt = config('secure.token_salt');
        return md5($randChars . $timestamp . $salt);
    }

    /**
     * 获取缓存用户信息
     * @param $key
     * @return mixed
     * @throws Exception
     * @throws TokenException
     */
    public static function getCurrentTokenVar($key)
    {
        $token = Request::instance()->header('token');
        $vars = Cache::get($token);
        if (empty($vars)) {
            throw new TokenException();
        } else {
            if (!is_array($vars)) {
                $vars = json_decode($vars, true);
            }
            if (array_key_exists($key, $vars)) {
                Cache::set($token,json_encode($vars),3600);//刷新缓存时间
                return $vars[$key];
            } else {
                throw  new TokenException();
            }
        }
    }
    /**
     * 获取用户id
     * @return mixed
     */
    public static function getCurrentUid()
    {
        $uid = self::getCurrentTokenVar('uid');
        return $uid;
    }
    /**
     * 根据token获取用户信息
     * @param $token
     * @return mixed
     * @throws TokenException
     */
    public static function getCurrentToken($token){
        $vars = Cache::get($token);
        if (empty($vars)) {
            throw new TokenException();
        } else {
            if (!is_array($vars)) {
                $vars = json_decode($vars, true);
                Cache::set($token,json_encode($vars),3600);//刷新缓存时间
            }
           return $vars;
        }
    }
    /**
     * 获取当前缓存的token值
     * @return string
     * @throws TokenException
     */
    public static function getCurrentTokenValue(){
        $token = Request::instance()->header('token');
        $vars = Cache::get($token);
        if (empty($vars)) {
            throw new TokenException();
        }
        return $token;
    }
    /**
     * 权限查看,管理员，用户都可以访问
     * @return bool
     * @throws ForbiddenException
     * @throws TokenException
     */
    public static function needPrimaryScope()
    {
        $scope = self::getCurrentTokenVar('scope');
        if (!empty($scope)) {
            if ($scope - ScopeEnum::USER >= 0) {
                return true;
            } else {
                throw new ForbiddenException();
            }
        } else {
            throw new TokenException();
        }
    }

    /**
     * 权限访问控制，只有用户可以访问
     * @return bool
     * @throws ForbiddenException
     * @throws TokenException
     */
    public static function needExclusiveScope()
    {
        $scope = self::getCurrentTokenVar('scope');
        if (!empty($scope)) {
            if ($scope == ScopeEnum::USER) {
                return true;
            } else {
                throw new ForbiddenException();
            }
        } else {
            throw new TokenException();
        }
    }

    /**
     * 新华扬CRM和新华扬人事权限检查
     * @return bool
     * @throws ForbiddenException
     * @throws TokenException
     */
    public static function permissionCheck(){
         $auth = self::getCurrentTokenVar('power');
        if (!empty($auth)) {
             if ($auth == AuthStatusEnum::ON){
                    return true;
             }else{
                 throw new ForbiddenException([
                     'code'=>200,
                     'msg'=>'权限不足，禁止访问',
                     'err_code'=>10001
                 ]);
             }
        } else {
            throw new TokenException();
        }
    }

    /**
     * 检查用户操作是否合法
     * @param $checkUID
     * @return bool
     * @throws Exception
     */
    public static function isValidOperate($checkUID)
    {
        if (!$checkUID){
         throw new Exception('检查用户uid时，必须传入一个uid');
        }
        $uid = self::getCurrentUid();
        if ($uid == $checkUID){
            return true;
        }
        return false;
    }

    /**
     * 判断token是否存在
     * @param $token
     * @return bool
     */
    public static function verifyToken($token){
        $exist = Cache::get($token);
        if ($exist){
            return true;
        }else{
            return false;
        }
    }
}